//
//  LowpassFilter.m
//  CocoaSynth
//
//  Created by Pierre DUCHENE on 16/02/10.
//  Copyright 2010 Pierre DUCHENE. All rights reserved.
//

#import "LowpassFilter.h"
#import "System.h"
#import "Sample.h"
#import "SignalVisualizer.h"

@implementation LowpassFilter

#pragma mark -
#pragma mark Accessors

@synthesize module;

#pragma mark -
#pragma mark Memory Management

- (id)init
{
	if (self = [super init]) {
		module = nil;
		lastValue = 0;
	}
	
	return self;
}

- (void)dealloc
{
	[module release];
	module = nil;
	
	[super dealloc];
}

#pragma mark -
#pragma mark ComputingStrategyProtocol

- (id<SampleProtocol>)execute
{	
	// Get all data we need
	System* system = [System sharedSystem];
	
	NSArray* inputSample = [[module inputSample] voltages];
	id<SampleProtocol> cutOffSample = [module cutOffFrequencySample];
	NSArray* cutOffFrequencySample = [cutOffSample voltages];
	float k = [module inputFrequencyModificator];
	float f0 =  kVCFFreqZero; 
	//float f0 = [module cutoffFrequency]; // TODO : see if f0 is really a setting
	
	NSMutableArray* cutSample = [[NSMutableArray alloc] init];
	
	for (int i = 0; i < [system sampleSize]; i++) {
		float newValue = [[cutOffFrequencySample objectAtIndex:i] floatValue] + k;
		[cutSample addObject:[NSNumber numberWithFloat:(f0 * pow(2, newValue))]];
	}
	
	float between = [system sampleSize] / [system sampleRate];
	NSMutableArray* newSample = [[NSMutableArray alloc] init];
	
	// Compute of the first value
	float firstValue = [[cutSample objectAtIndex:0] floatValue];
	float RC = 1 / (2 * M_PI * firstValue);
	float alpha = between / (RC + between);
	[newSample addObject:[NSNumber numberWithFloat:(lastValue + alpha * ([[inputSample objectAtIndex:0] floatValue] - lastValue))]]; 
	
	// Compute of the rest
	for (int i = 1; i < [system sampleSize]; i++) {
		float aValue = [[cutSample objectAtIndex:i] floatValue];
		float RC = 1 / (2 * M_PI * aValue);
		float alpha = between / (RC + between);
		[newSample addObject:[NSNumber numberWithFloat:([[newSample objectAtIndex:(i - 1)] floatValue]
														+ alpha * ([[inputSample objectAtIndex:i] floatValue]
														           - [[newSample objectAtIndex:(i - 1)] floatValue]))]]; 
	}
	
	id<SampleProtocol> result = [[Sample alloc] initWithVoltages:newSample];
	lastValue = [[newSample lastObject] floatValue];
	[cutSample release];
	[newSample release];
	
	return [result autorelease];
	
	/*float RC = 1.f/(2*M_PI*fc); // Don't need to use k???
	float dt = 1.f/[system sampleRate]; 
	float alpha = dt / (RC + dt);
	
	NSMutableArray* modifiedSample = [[NSMutableArray alloc] init];
	[modifiedSample insertObject:lastValue atIndex:0];
	for (int i = 1; i < [system sampleSize]; i++) {
		// See wikipedia lowpass algorithm ;-)
		float input = [[inputSample objectAtIndex:i] floatValue];
		float output  =  [[modifiedSample objectAtIndex:i-1] floatValue];
		float newValue =  alpha * input + (1 - alpha) * output;
		[modifiedSample insertObject:[NSNumber numberWithFloat:newValue] atIndex:i];
	}
	lastValue = [modifiedSample lastObject];
	id<SampleProtocol> result = [[Sample alloc] initWithVoltages:modifiedSample];
	[modifiedSample release];
	return [result autorelease];*/
}

@end
